Comparison of F0 curve only, no timing
Overall
As a first sanity check, let’s use the same comparison methods as d’Alessandro 2011. They took the correlation and the RMSE of vocal and chironomic imitations with the reference f0 curve.
- Median for vocal imitation: >0.9 correlation, <1.5ST RMSE
- Median for chironomic imitation: >0.8 correlation, <2.5ST RMSE
For our data:
all_data %>% filter(condition=="imitation") %>% pull(corr_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of vocal imitation")
[1] "0.957: Median correlation of vocal imitation"
all_data %>% filter(condition=="guide") %>% pull(corr_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of guided chironomic imitation")
[1] "0.903: Median correlation of guided chironomic imitation"
all_data %>% filter(condition=="blind") %>% pull(corr_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of blind chironomic imitation")
[1] "0.596: Median correlation of blind chironomic imitation"
all_data %>% filter(condition=="imitation") %>% pull(rmse_notiming) %>% median() %>%
round(3) %>% paste0(": Median RMSE of vocal imitation")
[1] "1.197: Median RMSE of vocal imitation"
all_data %>% filter(condition=="guide") %>% pull(rmse_notiming) %>% median() %>%
round(3) %>% paste0(": Median RMSE of guided chironomic imitation")
[1] "1.911: Median RMSE of guided chironomic imitation"
all_data %>% filter(condition=="blind") %>% pull(rmse_notiming) %>% median() %>%
round(3) %>% paste0(": Median RMSE of blind chironomic imitation")
[1] "3.112: Median RMSE of blind chironomic imitation"
In d’Alessandro 2011, the chironomic imitation was non-guided. The worse performance for non-guided imitation for our study may be explained by the added difficulty of finding the intonation curve and the correct timing control.
Slightly better scores arise for chironomic imitation when we use the stylized f0 curve as a reference. Stylization curve simplifies the f0 curve into straight line segments based on a perceptual model. The stylization removes microprosodic details present in natural vocal pronunciations that are not perceptually salient. Resynthesized utterances with f0 replaced by the stylized version are perceptually identical to the original.
Below are aggregate results for all data using the two types of references:
# Correlation
overall_psg_notiming <- all_data %>% ggplot(aes(x=condition, y=corr_psg_notiming)) +
geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values=wes_palette("Moonrise3")) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
labs(title="Correlation, No Timing", subtitle="Stylized reference",
x="Condition", y="Correlation")
overall_notiming <- all_data %>% ggplot(aes(x=condition, y=corr_notiming)) +
geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values=wes_palette("Moonrise3")) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
labs(title="", subtitle="Original reference",
x="Condition", y="Correlation")
# RMSE
overall_psg_rmse_notiming <- all_data %>% ggplot(aes(x=condition, y=rmse_psg_notiming)) +
geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values=wes_palette("Moonrise2")) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
labs(title="RMSE Scores, No Timing", subtitle="Stylized reference",
x="Condition", y="Correlation")
overall_rmse_notiming <- all_data %>% ggplot(aes(x=condition, y=rmse_notiming)) +
geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values=wes_palette("Moonrise2")) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
labs(title="", subtitle="Original reference",
x="Condition", y="Correlation")
grid.arrange(overall_psg_notiming, overall_notiming, overall_psg_rmse_notiming, overall_rmse_notiming, ncol=2)

all_data %>% filter(condition=="imitation") %>% pull(corr_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of vocal imitation")
[1] "0.957: Median correlation of vocal imitation"
all_data %>% filter(condition=="guide") %>% pull(corr_psg_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of Chironomic imitation")
[1] "0.944: Median correlation of Chironomic imitation"
all_data %>% filter(condition=="imitation") %>% pull(rmse_notiming) %>% median() %>%
round(3) %>% paste0(": Median RMSE of vocal imitation")
[1] "1.197: Median RMSE of vocal imitation"
all_data %>% filter(condition=="guide") %>% pull(rmse_psg_notiming) %>% median() %>%
round(3) %>% paste0(": Median RMSE of Chironomic imitation")
[1] "1.61: Median RMSE of Chironomic imitation"
For the rest of the comparison, we will be using the stylized version as a reference for the chironomic imitations and the original f0 curve for the vocal pronunciations. Chironomic pronunciations are always a stylization because it is both difficult and unncessary for the hands to produce the same micro-prosodic artifacts as the voice.
notiming_gest_data <- all_data %>% filter(type=='gesture') %>%
mutate(corr_notiming = corr_psg_notiming, rmse_notiming=rmse_psg_notiming)
notiming_voice_data <- all_data %>%filter(type=="voice")
notiming_data <-bind_rows(notiming_gest_data, notiming_voice_data)
Native vs Non-natives
Differences are slight between the learner and native groups in this study. This particular group of learners have all taken a class on French intonation and have encountered the phrases used in the study. Their performance for chironomic imitation is even slightly better than that of natives (probably not significant).
Natives have slightly better vocal scores. Their reading is also more similar to the originals when timing is not taken into account.
learners_box <- notiming_data %>% filter(subject %in% learners$id) %>%
ggplot(aes(x=condition, y=corr_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("GrandBudapest2")) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
labs(title="Correlation Scores (original ref)", subtitle="Learners")
natives_box <- notiming_data %>% filter(subject %in% natives$id) %>%
ggplot(aes(x=condition, y=corr_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("GrandBudapest2")) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
labs(title="", subtitle="Natives")
learners_box_rmse <- notiming_data %>% filter(subject %in% learners$id) %>%
ggplot(aes(x=condition, y=rmse_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("GrandBudapest1")) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
labs(title="RMSE Scores (original ref)", subtitle="Learners")
natives_box_rmse <- notiming_data %>% filter(subject %in% natives$id) %>%
ggplot(aes(x=condition, y=rmse_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("GrandBudapest1")) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
labs(title="", subtitle="Natives")
grid.arrange(learners_box, natives_box, learners_box_rmse, natives_box_rmse, ncol=2)

Musicians vs Non-musicians
7 of the 10 subjects in d’Alessandro 2011 had a musical practice. It may have helped their performance in the chironomic condition. In our study, 4 of the 10 subjects play music or sing. Musicians had slightly better scores for the blind chironomic condition. Their results are not different from non-musicians in the other conditions.
notiming_data %>% filter(subject %in% musicians$id & condition=="blind") %>% pull(corr_psg_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of blind chironomy - Musicians")
[1] "0.751: Median correlation of blind chironomy - Musicians"
notiming_data %>% filter(subject %in% nonmus$id & condition=="blind") %>% pull(corr_psg_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of blind chironomy - Non-musicians")
[1] "0.558: Median correlation of blind chironomy - Non-musicians"
notiming_data %>% filter(subject %in% musicians$id & condition=="blind") %>% pull(rmse_psg_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of blind chironomy - Musicians")
[1] "2.421: Median correlation of blind chironomy - Musicians"
notiming_data %>% filter(subject %in% nonmus$id & condition=="blind") %>% pull(rmse_psg_notiming) %>% median() %>%
round(3) %>% paste0(": Median correlation of blind chironomy - Non-musicians")
[1] "3.015: Median correlation of blind chironomy - Non-musicians"
musicians_box <- notiming_data %>% filter(subject %in% musicians$id) %>%
ggplot(aes(x=condition, y=corr_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("Chevalier1")) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
labs(title="Correlation Scores", subtitle="Musicians")
nonmus_box <- notiming_data %>% filter(subject %in% nonmus$id) %>%
ggplot(aes(x=condition, y=corr_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("Chevalier1")) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
labs(title="", subtitle="Non-musicians")
musicians_box_rmse <- notiming_data %>% filter(subject %in% musicians$id) %>%
ggplot(aes(x=condition, y=rmse_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("Royal2")) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
labs(title="RMSE Scores", subtitle="Musicians")
nonmus_box_rmse <- notiming_data %>% filter(subject %in% nonmus$id) %>%
ggplot(aes(x=condition, y=rmse_notiming)) + geom_boxplot(aes(fill=condition), show.legend = FALSE) +
scale_fill_manual(values = wes_palette("Royal2")) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
labs(title="", subtitle="Non-musicians")
grid.arrange(musicians_box, nonmus_box, musicians_box_rmse, nonmus_box_rmse, ncol=2)

By Phrase
For most phrases, guided chironomy and vocal imitation had comparable scores when timing is not taken into account. Both had higher than >0.9 median correlation for most phrases, and between 0.5 & 2.5ST median RMSE.
For half of the phrases (e.g. 2bis, 7, 8, 10, 11bis, 21bis), guided chironomy had higher median scores for correlation. Some of these phrases (10, 21bis), guided chironomy also had a better (lower) RMSE score.
Blind chironomy varied widely across phrases the phrases. Some phrases were notably more difficult even in the guided chironomy condition.
notiming_data %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=corr_notiming, fill=condition)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
geom_boxplot(width=0.7) +
scale_fill_manual(values = wes_palette("Moonrise3")) +
labs(title="Correlation Scores - all subjects",
subtitle="Grouped by phrase",
x="Phrase id", y="Correlation") #+ theme(aspect.ratio=0.4)

notiming_data %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=rmse_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_fill_manual(values = wes_palette("Moonrise1")) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
labs(title="RMSE Scores - all subject",
subtitle="Grouped by phrase",
x="Phrase id", y="RMSE") #+ theme(aspect.ratio=0.4)

Phrase and Native/Non-native
Natives and learners performed quite differently across the different phrases.
- For learners, reading (lecture) differed from the model the most for phrases 10, 10bis, 21.
- For non-natives, the only phrase that had median correlation <0.8 in the reading condition was 10bis
- For some phrases, blind chironomy had pretty good scores (correlation >0.8). These phrases were not all the same for n ative vs non-natives.
- For some phrases, in the blind chironomy condition, natives had lower scores than non-natives
In discussions after the study, a couple of native speakers reported not agreeing with the reference intonation curve provided for the guided chironomy condition.
c_l <- notiming_data %>% filter(subject %in% learners$id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=corr_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
scale_fill_manual(values = wes_palette("Moonrise3")) +
labs(title="Correlation Scores, no timing - Learners",
subtitle="Grouped by phrase",
x="Phrase id", y="Correlation") #+ theme(aspect.ratio=0.4)
c_n <- notiming_data %>% filter(subject %in% natives$id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=corr_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
scale_fill_manual(values = wes_palette("Moonrise3")) +
labs(title="Correlation Scores, no timing - Natives",
subtitle="Grouped by phrase",
x="Phrase id", y="Correlation") #+ theme(aspect.ratio=0.4)
grid.arrange(c_l, c_n, ncol=1)

r_l <- notiming_data %>% filter(subject %in% learners$id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=rmse_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(values = wes_palette("Royal2")) +
labs(title="RMSE Scores - Learners",
subtitle="Grouped by phrase",
x="Phrase id", y="RMSE")
r_n <- notiming_data %>% filter(subject %in% natives$id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=rmse_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(values = wes_palette("Royal2")) +
labs(title="RMSE Scores - Natives",
subtitle="Grouped by phrase",
x="Phrase id", y="RMSE")
grid.arrange(r_l, r_n, ncol=1)

By Phrase and Musician/Non-musician
In terms of correlation, musicians did much better than non-musicians in blind chironomy for a few specific phrases (e.g. 2, 7, 8). Some phrases were difficult for everyone (10bis, 21), but musicians still did better.
c_m <- notiming_data %>% filter(subject %in% musicians$id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=corr_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
scale_fill_manual(values = wes_palette("Moonrise3")) +
labs(title="Correlation Scores, no timing - Musicians",
subtitle="Grouped by phrase",
x="Phrase id", y="Correlation") #+ theme(aspect.ratio=0.4)
c_nm <- notiming_data %>% filter(subject %in% nonmus $id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=corr_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
scale_fill_manual(values = wes_palette("Moonrise3")) +
labs(title="Correlation Scores, no timing - Non-musicians",
subtitle="Grouped by phrase",
x="Phrase id", y="Correlation") #+ theme(aspect.ratio=0.4)
grid.arrange(c_m, c_nm, ncol=1)

r_m <- notiming_data %>% filter(subject %in% musicians$id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=rmse_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(values = wes_palette("Royal2")) +
labs(title="RMSE Scores - Musicians",
subtitle="Grouped by phrase",
x="Phrase id", y="RMSE")
r_nm <- notiming_data %>% filter(subject %in% nonmus$id) %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=rmse_notiming, fill=condition)) +
geom_boxplot(width=0.7) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(values = wes_palette("Royal2")) +
labs(title="RMSE Scores - Nonmus",
subtitle="Grouped by phrase",
x="Phrase id", y="RMSE")
grid.arrange(r_m, r_nm, ncol=1)

Taking Timing into account
For gestural comparisons, we need to make sure that we are comparing with the right part of the original signal. The part of the reference signal to be compared is taken from the beginning and ending scrub values of the gesture. The timing of the gesture is scaled linearly to match the timing of the reference.
For vocal comparisons, the part of the recording containing the utterance is labeled for both the reference and subject recordings. The timing of the vocal recording is scaled linearly to match the reference. No time warping was done in order to preserve the original rhythm of the recording.
# For gesture data, only keep the prosogram comparisons but call them the same thing as the corresponding comparisons for voice
gest_data2 <- all_data %>% filter(type=='gesture') %>% mutate(corr_notiming = corr_psg_notiming,
rmse_notiming = rmse_psg_notiming,
corr = corr_psg, rmse= rmse_psg)
long_data <- all_data %>% filter(type== 'voice') %>% bind_rows(gest_data2) %>%
# Get rid of columns containing the prosogram comparisons
mutate(corr_psg = NULL, rmse_psg = NULL, corr_psg_notiming = NULL, rmse_psg_notiming = NULL) %>%
# Make long version of data
pivot_longer(c('corr', 'corr_notiming', 'rmse', 'rmse_notiming'), names_to = "metrics", values_to = "score")
Overall
Interesting, the blind chironomy median scores don’t change much because they are already not so great. The scores for the other conditions are worse. Interestingly, guided chironomy performs the best when timing is taken into account. Even though its scores are slightly worse than when timing is not taken into account, it still manages to have “good” scores (in comparison with results from d’Alessandro 2011) – a median correlation of >0.8 and median RMSE around 2ST.
For reading, it is normal that there would be more variation in timing.
long_data %>% filter(metrics== 'corr_notiming' | metrics == 'corr') %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=0.2)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise3")) +
labs(title="Correlation, timing vs no-timing")

long_data %>% filter(metrics== 'rmse_notiming' | metrics == 'rmse') %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise2")) +
labs(title="RMSE, timing vs no-timing")

Learners vs Natives
Not so much difference between natives and non-natives when timing is taken into account.
l <- long_data %>% filter(metrics== 'corr_notiming' | metrics == 'corr') %>%
filter(subject %in% learners$id) %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=.2)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise3")) +
labs(title="Correlation, timing vs no-timing", subtitle="Learners")
n <- long_data %>% filter(metrics== 'corr_notiming' | metrics == 'corr') %>%
filter(subject %in% natives$id) %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=.2)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise3")) +
labs(subtitle="Natives")
grid.arrange(l, n, ncol=1)

l <- long_data %>% filter(metrics== 'rmse_notiming' | metrics == 'rmse') %>%
filter(subject %in% learners$id) %>%
ggplot(aes(x=condition, y=score)) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
geom_boxplot(aes(fill = metrics)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise2")) +
labs(title="RMSE, timing vs no-timing", subtitle="Learners")
n <- long_data %>% filter(metrics== 'rmse_notiming' | metrics == 'rmse') %>%
filter(subject %in% natives$id) %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise2")) +
labs(subtitle="Natives")
grid.arrange(l, n, ncol=1)

Musicians vs Non-musicians
Not big difference between musicians and non-musicians either when timing is taken into account.
m <- long_data %>% filter(metrics== 'corr_notiming' | metrics == 'corr') %>%
filter(subject %in% musicians$id) %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=.2)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise3")) +
labs(title="Correlation, timing vs no-timing", subtitle="Musicians")
nm <- long_data %>% filter(metrics== 'corr_notiming' | metrics == 'corr') %>%
filter(subject %in% nonmus$id) %>%
ggplot(aes(x=condition, y=score)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=.2)) +
geom_boxplot(aes(fill = metrics)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise3")) +
labs(subtitle="Non-musicians")
grid.arrange(m, nm, ncol=1)

m <- long_data %>% filter(metrics== 'rmse_notiming' | metrics == 'rmse') %>%
filter(subject %in% musicians$id) %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise2")) +
labs(title="RMSE, timing vs no-timing", subtitle="Learners")
nm <- long_data %>% filter(metrics== 'rmse_notiming' | metrics == 'rmse') %>%
filter(subject %in% nonmus$id) %>%
ggplot(aes(x=condition, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise2")) +
labs(subtitle="Natives")
grid.arrange(m, nm, ncol=1)

By Phrase
By compariing the difference between guided chironomy with and without timing taken into account, we can see that some phrases were trickier to control the timing of than others (e.g. 7bis, 10, 21, 21bis)
I’m not sure how meaningful it is to compare the vocal pronunciations with without dynamic time warping because there is natural variation in the voice.
ci <- long_data %>% filter(metrics== 'corr_notiming' | metrics == 'corr') %>%
filter(condition=='guide') %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=.2)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise3")) +
labs(title="Correlation, timing vs no-timing", subtitle="Guided Chironomy")
vi <- long_data %>% filter(metrics== 'corr_notiming' | metrics == 'corr') %>%
filter(condition=='imitation') %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(-0.8, 1, by=.2)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Moonrise3")) +
labs(title="Correlation, timing vs no-timing", subtitle="Vocal Comparison")
grid.arrange(ci, vi, ncol=1)

ci <- long_data %>% filter(metrics== 'rmse_notiming' | metrics == 'rmse') %>%
filter(condition=='guide') %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Royal2")) +
labs(title="RMSE, timing vs no-timing", subtitle="Guided Chironomy")
vi <- long_data %>% filter(metrics== 'rmse_notiming' | metrics == 'rmse') %>%
filter(condition=='imitation') %>%
mutate(pid = fct_relevel(pid, "2", "2bis", "7", "7bis", "8", "8bis",
"10", "10bis", "11", "11bis", "21", "21bis")) %>%
ggplot(aes(x=pid, y=score)) +
geom_boxplot(aes(fill = metrics)) +
scale_y_continuous(breaks=seq(0, 8, by=1)) +
scale_fill_manual(name = "Comparison type",
labels = c("With timing", "No timing"),
values=wes_palette("Royal2")) +
labs(title="RMSE, timing vs no-timing", subtitle="Vocal Comparison")
grid.arrange(ci, vi, ncol=1)

LS0tCnRpdGxlOiAiUGlsb3QgUGxvdHMgU3RvcnkiCm91dHB1dDogCiAgIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCgpgYGB7ciwgaW5jbHVkZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRSwgbWVzc2FnZXM9RkFMU0V9CmxpYnJhcnkoInRpZHl2ZXJzZSIpCmxpYnJhcnkoIndlc2FuZGVyc29uIikKbGlicmFyeSgiZ3JpZEV4dHJhIikKCiMgTG9hZCB0aGUgc2NvcmUgZGF0YQp2b2ljZV9kYXRhIDwtIHJlYWRSRFMoIi4uL2RhdGEvMjFfMDItc3R1ZHkvc2F2ZWQvdm9pY2Vfc2NvcmVzLnJkcyIpCmdlc3RzX2RhdGEgPC0gcmVhZFJEUygiLi4vZGF0YS8yMV8wMi1zdHVkeS9zYXZlZC9nZXN0X3Njb3Jlcy5yZHMiKQoKIyBNb2RpZnkgYW5kIGNvbWJpbmUgaW50byBhIGJpZyB0aWJibGUKZ2VzdHNfZGF0YSA8LSBnZXN0c19kYXRhICU+JSBzZWxlY3Qoc3ViamVjdCwgdHlwZSwgcGlkLCBvcmRlciwgcGhyYXNlLCBpZCwgY29yciwgY29ycl9wc2csIHJtc2UsIHJtc2VfcHNnLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycl9ub3RpbWluZywgY29ycl9wc2dfbm90aW1pbmcsIHJtc2Vfbm90aW1pbmcsIHJtc2VfcHNnX25vdGltaW5nKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUoY29uZGl0aW9uPXR5cGUpICU+JSBtdXRhdGUodHlwZT0iZ2VzdHVyZSIpCnZvaWNlX2RhdGEgPC0gdm9pY2VfZGF0YSAlPiUgc2VsZWN0KHN1YmplY3QsIHR5cGUsIHBpZCwgb3JkZXIsIHBocmFzZSwgaWQsIGNvcnIsIGNvcnJfcHNnLCBybXNlLCBybXNlX3BzZywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJfbm90aW1pbmcsIGNvcnJfcHNnX25vdGltaW5nLCBybXNlX25vdGltaW5nLCBybXNlX3BzZ19ub3RpbWluZykgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKGNvbmRpdGlvbj10eXBlKSAlPiUgbXV0YXRlKHR5cGU9InZvaWNlIikKCmFsbF9kYXRhIDwtIGJpbmRfcm93cyhnZXN0c19kYXRhLCB2b2ljZV9kYXRhKQoKIyBTdWJqZWN0cyBhbmQgdHlwZXMKc3ViamVjdHMgPC0gcmVhZF90c3YoIi4uL2RhdGEvMjFfMDItc3R1ZHkvc3ViamVjdHMudHN2IikKbmF0aXZlcyA8LSBzdWJqZWN0cyAlPiUgZmlsdGVyKGx2bF9mcmVuY2ggPT0gIk4iKQpsZWFybmVycyA8LSBzdWJqZWN0cyAlPiUgZmlsdGVyKGx2bF9mcmVuY2ggIT0gIk4iKQptdXNpY2lhbnMgPC0gc3ViamVjdHMgJT4lIGZpbHRlcihtdXNpYyA9PSAiWSIpCm5vbm11cyA8LSBzdWJqZWN0cyAlPiUgZmlsdGVyKG11c2ljICE9ICJZIikKYGBgCgojIENvbXBhcmlzb24gb2YgRjAgY3VydmUgb25seSwgbm8gdGltaW5nCgojIyBPdmVyYWxsCgpBcyBhIGZpcnN0IHNhbml0eSBjaGVjaywgbGV0J3MgdXNlIHRoZSBzYW1lIGNvbXBhcmlzb24gbWV0aG9kcyBhcyBkJ0FsZXNzYW5kcm8gMjAxMS4gVGhleSB0b29rIHRoZSBjb3JyZWxhdGlvbiBhbmQgdGhlIFJNU0Ugb2Ygdm9jYWwgYW5kIGNoaXJvbm9taWMgaW1pdGF0aW9ucyB3aXRoIHRoZSByZWZlcmVuY2UgZjAgY3VydmUuIAoKKiBNZWRpYW4gZm9yIHZvY2FsIGltaXRhdGlvbjogPjAuOSBjb3JyZWxhdGlvbiwgPDEuNVNUIFJNU0UKKiBNZWRpYW4gZm9yIGNoaXJvbm9taWMgaW1pdGF0aW9uOiA+MC44IGNvcnJlbGF0aW9uLCA8Mi41U1QgUk1TRQoKRm9yIG91ciBkYXRhOgpgYGB7cn0KYWxsX2RhdGEgJT4lIGZpbHRlcihjb25kaXRpb249PSJpbWl0YXRpb24iKSAlPiUgcHVsbChjb3JyX25vdGltaW5nKSAlPiUgbWVkaWFuKCkgJT4lIAogIHJvdW5kKDMpICU+JSBwYXN0ZTAoIjogTWVkaWFuIGNvcnJlbGF0aW9uIG9mIHZvY2FsIGltaXRhdGlvbiIpCgphbGxfZGF0YSAlPiUgZmlsdGVyKGNvbmRpdGlvbj09Imd1aWRlIikgJT4lIHB1bGwoY29ycl9ub3RpbWluZykgJT4lIG1lZGlhbigpICU+JQogIHJvdW5kKDMpICU+JSBwYXN0ZTAoIjogTWVkaWFuIGNvcnJlbGF0aW9uIG9mIGd1aWRlZCBjaGlyb25vbWljIGltaXRhdGlvbiIpCgphbGxfZGF0YSAlPiUgZmlsdGVyKGNvbmRpdGlvbj09ImJsaW5kIikgJT4lIHB1bGwoY29ycl9ub3RpbWluZykgJT4lIG1lZGlhbigpICU+JSAKICByb3VuZCgzKSAlPiUgcGFzdGUwKCI6IE1lZGlhbiBjb3JyZWxhdGlvbiBvZiBibGluZCBjaGlyb25vbWljIGltaXRhdGlvbiIpCgphbGxfZGF0YSAlPiUgZmlsdGVyKGNvbmRpdGlvbj09ImltaXRhdGlvbiIpICU+JSBwdWxsKHJtc2Vfbm90aW1pbmcpICU+JSBtZWRpYW4oKSAlPiUgCiAgcm91bmQoMykgJT4lIHBhc3RlMCgiOiBNZWRpYW4gUk1TRSBvZiB2b2NhbCBpbWl0YXRpb24iKQoKYWxsX2RhdGEgJT4lIGZpbHRlcihjb25kaXRpb249PSJndWlkZSIpICU+JSBwdWxsKHJtc2Vfbm90aW1pbmcpICU+JSBtZWRpYW4oKSAlPiUKICByb3VuZCgzKSAlPiUgcGFzdGUwKCI6IE1lZGlhbiBSTVNFIG9mIGd1aWRlZCBjaGlyb25vbWljIGltaXRhdGlvbiIpCgphbGxfZGF0YSAlPiUgZmlsdGVyKGNvbmRpdGlvbj09ImJsaW5kIikgJT4lIHB1bGwocm1zZV9ub3RpbWluZykgJT4lIG1lZGlhbigpICU+JSAKICByb3VuZCgzKSAlPiUgcGFzdGUwKCI6IE1lZGlhbiBSTVNFIG9mIGJsaW5kIGNoaXJvbm9taWMgaW1pdGF0aW9uIikKYGBgCgpJbiBkJ0FsZXNzYW5kcm8gMjAxMSwgdGhlIGNoaXJvbm9taWMgaW1pdGF0aW9uIHdhcyBub24tZ3VpZGVkLiBUaGUgd29yc2UgcGVyZm9ybWFuY2UgZm9yIG5vbi1ndWlkZWQgaW1pdGF0aW9uIGZvciBvdXIgc3R1ZHkgbWF5IGJlIGV4cGxhaW5lZCBieSB0aGUgYWRkZWQgZGlmZmljdWx0eSBvZiBmaW5kaW5nIHRoZSBpbnRvbmF0aW9uIGN1cnZlIGFuZCB0aGUgY29ycmVjdCB0aW1pbmcgY29udHJvbC4KClNsaWdodGx5IGJldHRlciBzY29yZXMgYXJpc2UgZm9yIGNoaXJvbm9taWMgaW1pdGF0aW9uIHdoZW4gd2UgdXNlIHRoZSBzdHlsaXplZCBmMCBjdXJ2ZSBhcyBhIHJlZmVyZW5jZS4gU3R5bGl6YXRpb24gY3VydmUgc2ltcGxpZmllcyB0aGUgZjAgY3VydmUgaW50byBzdHJhaWdodCBsaW5lIHNlZ21lbnRzIGJhc2VkIG9uIGEgcGVyY2VwdHVhbCBtb2RlbC4gVGhlIHN0eWxpemF0aW9uIHJlbW92ZXMgbWljcm9wcm9zb2RpYyBkZXRhaWxzIHByZXNlbnQgaW4gbmF0dXJhbCB2b2NhbCBwcm9udW5jaWF0aW9ucyB0aGF0IGFyZSBub3QgcGVyY2VwdHVhbGx5IHNhbGllbnQuIFJlc3ludGhlc2l6ZWQgdXR0ZXJhbmNlcyB3aXRoIGYwIHJlcGxhY2VkIGJ5IHRoZSBzdHlsaXplZCB2ZXJzaW9uIGFyZSBwZXJjZXB0dWFsbHkgaWRlbnRpY2FsIHRvIHRoZSBvcmlnaW5hbC4gCgpCZWxvdyBhcmUgYWdncmVnYXRlIHJlc3VsdHMgZm9yIGFsbCBkYXRhIHVzaW5nIHRoZSB0d28gdHlwZXMgb2YgcmVmZXJlbmNlczoKCmBgYHtyfQojIENvcnJlbGF0aW9uCm92ZXJhbGxfcHNnX25vdGltaW5nIDwtIGFsbF9kYXRhICU+JSBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PWNvcnJfcHNnX25vdGltaW5nKSkgKyAKICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbD1jb25kaXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0wLjIpKSArCiAgICAgICAgICAgICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiwgTm8gdGltaW5nIiwgc3VidGl0bGU9IlN0eWxpemVkIHJlZmVyZW5jZSIsCiAgICAgICAgICAgICAgeD0iQ29uZGl0aW9uIiwgeT0iQ29ycmVsYXRpb24iKSAKCm92ZXJhbGxfbm90aW1pbmcgPC0gYWxsX2RhdGEgJT4lIGdncGxvdChhZXMoeD1jb25kaXRpb24sIHk9Y29ycl9ub3RpbWluZykpICsgCiAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Y29uZGl0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PTAuMikpICsKICAgICAgICAgICAgIGxhYnModGl0bGU9IiIsIHN1YnRpdGxlPSJPcmlnaW5hbCByZWZlcmVuY2UiLAogICAgICAgICAgICAgIHg9IkNvbmRpdGlvbiIsIHk9IkNvcnJlbGF0aW9uIikgCgojIFJNU0UKb3ZlcmFsbF9wc2dfcm1zZV9ub3RpbWluZyA8LSBhbGxfZGF0YSAlPiUgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbiwgeT1ybXNlX3BzZ19ub3RpbWluZykpICsgCiAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Y29uZGl0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTIiKSkgKwogICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwgOCwgYnk9MSkpICsgCiAgICAgICAgICAgICBsYWJzKHRpdGxlPSJSTVNFIFNjb3JlcywgTm8gdGltaW5nIiwgc3VidGl0bGU9IlN0eWxpemVkIHJlZmVyZW5jZSIsCiAgICAgICAgICAgICAgeD0iQ29uZGl0aW9uIiwgeT0iQ29ycmVsYXRpb24iKSAKCm92ZXJhbGxfcm1zZV9ub3RpbWluZyA8LSBhbGxfZGF0YSAlPiUgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbiwgeT1ybXNlX25vdGltaW5nKSkgKyAKICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbD1jb25kaXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMiIpKSArCiAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCA4LCBieT0xKSkgKyAKICAgICAgICAgICAgIGxhYnModGl0bGU9IiIsIHN1YnRpdGxlPSJPcmlnaW5hbCByZWZlcmVuY2UiLAogICAgICAgICAgICAgIHg9IkNvbmRpdGlvbiIsIHk9IkNvcnJlbGF0aW9uIikgCgpncmlkLmFycmFuZ2Uob3ZlcmFsbF9wc2dfbm90aW1pbmcsIG92ZXJhbGxfbm90aW1pbmcsIG92ZXJhbGxfcHNnX3Jtc2Vfbm90aW1pbmcsIG92ZXJhbGxfcm1zZV9ub3RpbWluZywgbmNvbD0yKQoKYGBgCgpgYGB7cn0KYWxsX2RhdGEgJT4lIGZpbHRlcihjb25kaXRpb249PSJpbWl0YXRpb24iKSAlPiUgcHVsbChjb3JyX25vdGltaW5nKSAlPiUgbWVkaWFuKCkgJT4lIAogIHJvdW5kKDMpICU+JSBwYXN0ZTAoIjogTWVkaWFuIGNvcnJlbGF0aW9uIG9mIHZvY2FsIGltaXRhdGlvbiIpCgphbGxfZGF0YSAlPiUgZmlsdGVyKGNvbmRpdGlvbj09Imd1aWRlIikgJT4lIHB1bGwoY29ycl9wc2dfbm90aW1pbmcpICU+JSBtZWRpYW4oKSAlPiUKICByb3VuZCgzKSAlPiUgcGFzdGUwKCI6IE1lZGlhbiBjb3JyZWxhdGlvbiBvZiBjaGlyb25vbWljIGltaXRhdGlvbiIpCgphbGxfZGF0YSAlPiUgZmlsdGVyKGNvbmRpdGlvbj09ImltaXRhdGlvbiIpICU+JSBwdWxsKHJtc2Vfbm90aW1pbmcpICU+JSBtZWRpYW4oKSAlPiUgCiAgcm91bmQoMykgJT4lIHBhc3RlMCgiOiBNZWRpYW4gUk1TRSBvZiB2b2NhbCBpbWl0YXRpb24iKQoKYWxsX2RhdGEgJT4lIGZpbHRlcihjb25kaXRpb249PSJndWlkZSIpICU+JSBwdWxsKHJtc2VfcHNnX25vdGltaW5nKSAlPiUgbWVkaWFuKCkgJT4lCiAgcm91bmQoMykgJT4lIHBhc3RlMCgiOiBNZWRpYW4gUk1TRSBvZiBjaGlyb25vbWljIGltaXRhdGlvbiIpCmBgYAoKRm9yIHRoZSByZXN0IG9mIHRoZSBjb21wYXJpc29uLCB3ZSB3aWxsIGJlIHVzaW5nIHRoZSBzdHlsaXplZCB2ZXJzaW9uIGFzIGEgcmVmZXJlbmNlIGZvciB0aGUgY2hpcm9ub21pYyBpbWl0YXRpb25zIGFuZCB0aGUgb3JpZ2luYWwgZjAgY3VydmUgZm9yIHRoZSB2b2NhbCBwcm9udW5jaWF0aW9ucy4gQ2hpcm9ub21pYyBwcm9udW5jaWF0aW9ucyBhcmUgYWx3YXlzIGEgc3R5bGl6YXRpb24gYmVjYXVzZSBpdCBpcyBib3RoIGRpZmZpY3VsdCBhbmQgdW5uY2Vzc2FyeSBmb3IgdGhlIGhhbmRzIHRvIHByb2R1Y2UgdGhlIHNhbWUgbWljcm8tcHJvc29kaWMgYXJ0aWZhY3RzIGFzIHRoZSB2b2ljZS4KCmBgYHtyfQpub3RpbWluZ19nZXN0X2RhdGEgPC0gYWxsX2RhdGEgJT4lIGZpbHRlcih0eXBlPT0nZ2VzdHVyZScpICU+JSAKICAgICAgICAgICAgICAgICBtdXRhdGUoY29ycl9ub3RpbWluZyA9IGNvcnJfcHNnX25vdGltaW5nLCBybXNlX25vdGltaW5nPXJtc2VfcHNnX25vdGltaW5nKSAKbm90aW1pbmdfdm9pY2VfZGF0YSA8LSBhbGxfZGF0YSAlPiVmaWx0ZXIodHlwZT09InZvaWNlIikgICAgICAgICAgCm5vdGltaW5nX2RhdGEgPC1iaW5kX3Jvd3Mobm90aW1pbmdfZ2VzdF9kYXRhLCBub3RpbWluZ192b2ljZV9kYXRhKQpgYGAKCiMjIE5hdGl2ZSB2cyBOb24tbmF0aXZlcwoKRGlmZmVyZW5jZXMgYXJlIHNsaWdodCBiZXR3ZWVuIHRoZSBsZWFybmVyIGFuZCBuYXRpdmUgZ3JvdXBzIGluIHRoaXMgc3R1ZHkuIFRoaXMgcGFydGljdWxhciBncm91cCBvZiBsZWFybmVycyBoYXZlIGFsbCB0YWtlbiBhIGNsYXNzIG9uIEZyZW5jaCBpbnRvbmF0aW9uIGFuZCBoYXZlIGVuY291bnRlcmVkIHRoZSBwaHJhc2VzIHVzZWQgaW4gdGhlIHN0dWR5LiBUaGVpciBwZXJmb3JtYW5jZSBmb3IgY2hpcm9ub21pYyBpbWl0YXRpb24gaXMgZXZlbiBzbGlnaHRseSBiZXR0ZXIgdGhhbiB0aGF0IG9mIG5hdGl2ZXMgKHByb2JhYmx5IG5vdCBzaWduaWZpY2FudCkuIAoKTmF0aXZlcyBoYXZlIHNsaWdodGx5IGJldHRlciB2b2NhbCBzY29yZXMuIFRoZWlyIHJlYWRpbmcgaXMgYWxzbyBtb3JlIHNpbWlsYXIgdG8gdGhlIG9yaWdpbmFscyB3aGVuIHRpbWluZyBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LgoKYGBge3J9CmxlYXJuZXJzX2JveCA8LSBub3RpbWluZ19kYXRhICU+JSBmaWx0ZXIoc3ViamVjdCAlaW4lIGxlYXJuZXJzJGlkKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PWNvcnJfbm90aW1pbmcpKSArIGdlb21fYm94cGxvdChhZXMoZmlsbD1jb25kaXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIkdyYW5kQnVkYXBlc3QyIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0wLjIpKSArCiAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24gU2NvcmVzLCBubyB0aW1pbmciLCBzdWJ0aXRsZT0iTGVhcm5lcnMiKSAKICAgICAgICAgICAgICAgICAgICAKbmF0aXZlc19ib3ggPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBuYXRpdmVzJGlkKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PWNvcnJfbm90aW1pbmcpKSArIGdlb21fYm94cGxvdChhZXMoZmlsbD1jb25kaXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIkdyYW5kQnVkYXBlc3QyIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0wLjIpKSArCiAgbGFicyh0aXRsZT0iIiwgc3VidGl0bGU9Ik5hdGl2ZXMiKSAgICAgICAgICAgICAgICAgICAgCgpsZWFybmVyc19ib3hfcm1zZSA8LSBub3RpbWluZ19kYXRhICU+JSBmaWx0ZXIoc3ViamVjdCAlaW4lIGxlYXJuZXJzJGlkKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PXJtc2Vfbm90aW1pbmcpKSArIGdlb21fYm94cGxvdChhZXMoZmlsbD1jb25kaXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIkdyYW5kQnVkYXBlc3QxIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCA4LCBieT0xKSkgKyAKICBsYWJzKHRpdGxlPSJSTVNFIFNjb3Jlcywgbm8gdGltaW5nIiwgc3VidGl0bGU9IkxlYXJuZXJzIikgCiAgICAgICAgICAgICAgICAgICAgCm5hdGl2ZXNfYm94X3Jtc2UgPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBuYXRpdmVzJGlkKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PXJtc2Vfbm90aW1pbmcpKSArIGdlb21fYm94cGxvdChhZXMoZmlsbD1jb25kaXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIkdyYW5kQnVkYXBlc3QxIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCA4LCBieT0xKSkgKyAKICBsYWJzKHRpdGxlPSIiLCBzdWJ0aXRsZT0iTmF0aXZlcyIpICAgICAgICAgICAgICAgICAgICAKCmdyaWQuYXJyYW5nZShsZWFybmVyc19ib3gsIG5hdGl2ZXNfYm94LCBsZWFybmVyc19ib3hfcm1zZSwgbmF0aXZlc19ib3hfcm1zZSwgbmNvbD0yKSAKYGBgCgojIyBNdXNpY2lhbnMgdnMgTm9uLW11c2ljaWFucwoKNyBvZiB0aGUgMTAgc3ViamVjdHMgaW4gZCdBbGVzc2FuZHJvIDIwMTEgaGFkIGEgbXVzaWNhbCBwcmFjdGljZS4gSXQgbWF5IGhhdmUgaGVscGVkIHRoZWlyIHBlcmZvcm1hbmNlIGluIHRoZSBjaGlyb25vbWljIGNvbmRpdGlvbi4gSW4gb3VyIHN0dWR5LCA0IG9mIHRoZSAxMCBzdWJqZWN0cyBwbGF5IG11c2ljIG9yIHNpbmcuIE11c2ljaWFucyBoYWQgc2xpZ2h0bHkgYmV0dGVyIHNjb3JlcyBmb3IgdGhlIGJsaW5kIGNoaXJvbm9taWMgY29uZGl0aW9uLiBUaGVpciByZXN1bHRzIGFyZSBub3QgZGlmZmVyZW50IGZyb20gbm9uLW11c2ljaWFucyBpbiB0aGUgb3RoZXIgY29uZGl0aW9ucy4KCmBgYHtyfQpub3RpbWluZ19kYXRhICU+JSBmaWx0ZXIoc3ViamVjdCAlaW4lIG11c2ljaWFucyRpZCAmIGNvbmRpdGlvbj09ImJsaW5kIikgJT4lIHB1bGwoY29ycl9wc2dfbm90aW1pbmcpICU+JSBtZWRpYW4oKSAlPiUgCiAgcm91bmQoMykgJT4lIHBhc3RlMCgiOiBNZWRpYW4gY29ycmVsYXRpb24gb2YgYmxpbmQgY2hpcm9ub215IC0gTXVzaWNpYW5zIikKCm5vdGltaW5nX2RhdGEgJT4lIGZpbHRlcihzdWJqZWN0ICVpbiUgbm9ubXVzJGlkICYgY29uZGl0aW9uPT0iYmxpbmQiKSAlPiUgcHVsbChjb3JyX3BzZ19ub3RpbWluZykgJT4lIG1lZGlhbigpICU+JSAKICByb3VuZCgzKSAlPiUgcGFzdGUwKCI6IE1lZGlhbiBjb3JyZWxhdGlvbiBvZiBibGluZCBjaGlyb25vbXkgLSBOb24tbXVzaWNpYW5zIikKCm5vdGltaW5nX2RhdGEgJT4lIGZpbHRlcihzdWJqZWN0ICVpbiUgbXVzaWNpYW5zJGlkICYgY29uZGl0aW9uPT0iYmxpbmQiKSAlPiUgcHVsbChybXNlX3BzZ19ub3RpbWluZykgJT4lIG1lZGlhbigpICU+JSAKICByb3VuZCgzKSAlPiUgcGFzdGUwKCI6IE1lZGlhbiBjb3JyZWxhdGlvbiBvZiBibGluZCBjaGlyb25vbXkgLSBNdXNpY2lhbnMiKQoKbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBub25tdXMkaWQgJiBjb25kaXRpb249PSJibGluZCIpICU+JSBwdWxsKHJtc2VfcHNnX25vdGltaW5nKSAlPiUgbWVkaWFuKCkgJT4lIAogIHJvdW5kKDMpICU+JSBwYXN0ZTAoIjogTWVkaWFuIGNvcnJlbGF0aW9uIG9mIGJsaW5kIGNoaXJvbm9teSAtIE5vbi1tdXNpY2lhbnMiKQpgYGAKCgpgYGB7cn0KbXVzaWNpYW5zX2JveCA8LSBub3RpbWluZ19kYXRhICU+JSBmaWx0ZXIoc3ViamVjdCAlaW4lIG11c2ljaWFucyRpZCkgJT4lCiAgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbiwgeT1jb3JyX25vdGltaW5nKSkgKyBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Y29uZGl0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJDaGV2YWxpZXIxIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0wLjIpKSArCiAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24gU2NvcmVzLCBubyB0aW1pbmciLCBzdWJ0aXRsZT0iTXVzaWNpYW5zIikKICAgICAgICAgICAgICAgICAgICAKbm9ubXVzX2JveCA8LSBub3RpbWluZ19kYXRhICU+JSBmaWx0ZXIoc3ViamVjdCAlaW4lIG5vbm11cyRpZCkgJT4lCiAgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbiwgeT1jb3JyX25vdGltaW5nKSkgKyBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Y29uZGl0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJDaGV2YWxpZXIxIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0wLjIpKSArCiAgbGFicyh0aXRsZT0iIiwgc3VidGl0bGU9Ik5vbi1tdXNpY2lhbnMiKSAgICAgICAgICAgICAgICAgICAgCiAKbXVzaWNpYW5zX2JveF9ybXNlIDwtIG5vdGltaW5nX2RhdGEgJT4lIGZpbHRlcihzdWJqZWN0ICVpbiUgbXVzaWNpYW5zJGlkKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PXJtc2Vfbm90aW1pbmcpKSArIGdlb21fYm94cGxvdChhZXMoZmlsbD1jb25kaXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMiIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwgOCwgYnk9MSkpICsgCiAgbGFicyh0aXRsZT0iUk1TRSBTY29yZXMsIG5vIHRpbWluZyIsIHN1YnRpdGxlPSJNdXNpY2lhbnMiKQogICAgICAgICAgICAgICAgICAgIApub25tdXNfYm94X3Jtc2UgPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBub25tdXMkaWQpICU+JQogIGdncGxvdChhZXMoeD1jb25kaXRpb24sIHk9cm1zZV9ub3RpbWluZykpICsgZ2VvbV9ib3hwbG90KGFlcyhmaWxsPWNvbmRpdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwyIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCA4LCBieT0xKSkgKyAKICBsYWJzKHRpdGxlPSIiLCBzdWJ0aXRsZT0iTm9uLW11c2ljaWFucyIpICAgICAKCmdyaWQuYXJyYW5nZShtdXNpY2lhbnNfYm94LCBub25tdXNfYm94LCBtdXNpY2lhbnNfYm94X3Jtc2UsIG5vbm11c19ib3hfcm1zZSwgbmNvbD0yKQpgYGAKCiMjIEJ5IFBocmFzZQoKRm9yIG1vc3QgcGhyYXNlcywgZ3VpZGVkIGNoaXJvbm9teSBhbmQgdm9jYWwgaW1pdGF0aW9uIGhhZCBjb21wYXJhYmxlIHNjb3JlcyB3aGVuIHRpbWluZyBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LiBCb3RoIGhhZCBoaWdoZXIgdGhhbiA+MC45IG1lZGlhbiBjb3JyZWxhdGlvbiBmb3IgbW9zdCBwaHJhc2VzLCBhbmQgYmV0d2VlbiAwLjUgJiAyLjVTVCBtZWRpYW4gUk1TRS4KCkZvciBoYWxmIG9mIHRoZSBwaHJhc2VzIChlLmcuIDJiaXMsIDcsIDgsIDEwLCAxMWJpcywgMjFiaXMpLCBndWlkZWQgY2hpcm9ub215IGhhZCBoaWdoZXIgbWVkaWFuIHNjb3JlcyBmb3IgY29ycmVsYXRpb24uIFNvbWUgb2YgdGhlc2UgcGhyYXNlcyAoMTAsIDIxYmlzKSwgZ3VpZGVkIGNoaXJvbm9teSBhbHNvIGhhZCBhIGJldHRlciAobG93ZXIpIFJNU0Ugc2NvcmUuCgpCbGluZCBjaGlyb25vbXkgdmFyaWVkIHdpZGVseSBhY3Jvc3MgcGhyYXNlcyB0aGUgcGhyYXNlcy4gU29tZSBwaHJhc2VzIHdlcmUgbm90YWJseSBtb3JlIGRpZmZpY3VsdCBldmVuIGluIHRoZSBndWlkZWQgY2hpcm9ub215IGNvbmRpdGlvbi4KCmBgYHtyfQpub3RpbWluZ19kYXRhICU+JQogIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PWNvcnJfbm90aW1pbmcsIGZpbGw9Y29uZGl0aW9uKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PTAuMikpICsKICBnZW9tX2JveHBsb3Qod2lkdGg9MC43KSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogIGxhYnModGl0bGU9IkNvcnJlbGF0aW9uIFNjb3Jlcywgbm8gdGltaW5nIC0gYWxsIHN1YmplY3RzIiwgCiAgICAgICAgICAgIHN1YnRpdGxlPSJHcm91cGVkIGJ5IHBocmFzZSIsCiAgICAgICAgICAgIHg9IlBocmFzZSBpZCIsIHk9IkNvcnJlbGF0aW9uIikgIysgdGhlbWUoYXNwZWN0LnJhdGlvPTAuNCkKYGBgCgpgYGB7cn0Kbm90aW1pbmdfZGF0YSAlPiUKICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgZ2dwbG90KGFlcyh4PXBpZCwgeT1ybXNlX25vdGltaW5nLCBmaWxsPWNvbmRpdGlvbikpICsKICBnZW9tX2JveHBsb3Qod2lkdGg9MC43KSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJNb29ucmlzZTEiKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsIDgsIGJ5PTEpKSArIAogIGxhYnModGl0bGU9IlJNU0UgU2NvcmVzLCBubyB0aW1pbmcgLSBhbGwgc3ViamVjdCIsIAogICAgICAgICAgICBzdWJ0aXRsZT0iR3JvdXBlZCBieSBwaHJhc2UiLAogICAgICAgICAgICB4PSJQaHJhc2UgaWQiLCB5PSJSTVNFIikgIysgdGhlbWUoYXNwZWN0LnJhdGlvPTAuNCkKYGBgCgojIyBQaHJhc2UgYW5kIE5hdGl2ZS9Ob24tbmF0aXZlCgpOYXRpdmVzIGFuZCBsZWFybmVycyBwZXJmb3JtZWQgcXVpdGUgZGlmZmVyZW50bHkgYWNyb3NzIHRoZSBkaWZmZXJlbnQgcGhyYXNlcy4gIAoKKiBGb3IgbGVhcm5lcnMsIHJlYWRpbmcgKGxlY3R1cmUpIGRpZmZlcmVkIGZyb20gdGhlIG1vZGVsIHRoZSBtb3N0IGZvciBwaHJhc2VzIDEwLCAxMGJpcywgMjEuCiogRm9yIG5vbi1uYXRpdmVzLCB0aGUgb25seSBwaHJhc2UgdGhhdCBoYWQgbWVkaWFuIGNvcnJlbGF0aW9uIDwwLjggaW4gdGhlIHJlYWRpbmcgY29uZGl0aW9uIHdhcyAxMGJpcwoqIEZvciBzb21lIHBocmFzZXMsIGJsaW5kIGNoaXJvbm9teSBoYWQgcHJldHR5IGdvb2Qgc2NvcmVzIChjb3JyZWxhdGlvbiA+MC44KS4gVGhlc2UgcGhyYXNlcyB3ZXJlIG5vdCBhbGwgdGhlIHNhbWUgZm9yIG4gYXRpdmUgdnMgbm9uLW5hdGl2ZXMuCiogRm9yIHNvbWUgcGhyYXNlcywgaW4gdGhlIGJsaW5kIGNoaXJvbm9teSBjb25kaXRpb24sIG5hdGl2ZXMgaGFkIGxvd2VyIHNjb3JlcyB0aGFuIG5vbi1uYXRpdmVzCgpJbiBkaXNjdXNzaW9ucyBhZnRlciB0aGUgc3R1ZHksIGEgY291cGxlIG9mIG5hdGl2ZSBzcGVha2VycyByZXBvcnRlZCBub3QgYWdyZWVpbmcgd2l0aCB0aGUgcmVmZXJlbmNlIGludG9uYXRpb24gY3VydmUgcHJvdmlkZWQgZm9yIHRoZSBndWlkZWQgY2hpcm9ub215IGNvbmRpdGlvbi4KCmBgYHtyfQpjX2wgPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBsZWFybmVycyRpZCkgJT4lCiAgbXV0YXRlKHBpZCA9IGZjdF9yZWxldmVsKHBpZCwgIjIiLCAiMmJpcyIsICI3IiwgIjdiaXMiLCAiOCIsICI4YmlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIiwgIjEwYmlzIiwgIjExIiwgIjExYmlzIiwgIjIxIiwgIjIxYmlzIikpICU+JQogIGdncGxvdChhZXMoeD1waWQsIHk9Y29ycl9ub3RpbWluZywgZmlsbD1jb25kaXRpb24pKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoPTAuNykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0wLjIpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24gU2NvcmVzLCBubyB0aW1pbmcgLSBMZWFybmVycyIsIAogICAgICAgICAgICBzdWJ0aXRsZT0iR3JvdXBlZCBieSBwaHJhc2UiLAogICAgICAgICAgICB4PSJQaHJhc2UgaWQiLCB5PSJDb3JyZWxhdGlvbiIpICMrIHRoZW1lKGFzcGVjdC5yYXRpbz0wLjQpCgpjX24gPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBuYXRpdmVzJGlkKSAlPiUKICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgZ2dwbG90KGFlcyh4PXBpZCwgeT1jb3JyX25vdGltaW5nLCBmaWxsPWNvbmRpdGlvbikpICsKICBnZW9tX2JveHBsb3Qod2lkdGg9MC43KSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PTAuMikpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiTW9vbnJpc2UzIikpICsKICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiBTY29yZXMsIG5vIHRpbWluZyAtIE5hdGl2ZXMiLCAKICAgICAgICAgICAgc3VidGl0bGU9Ikdyb3VwZWQgYnkgcGhyYXNlIiwKICAgICAgICAgICAgeD0iUGhyYXNlIGlkIiwgeT0iQ29ycmVsYXRpb24iKSAjKyB0aGVtZShhc3BlY3QucmF0aW89MC40KQoKZ3JpZC5hcnJhbmdlKGNfbCwgY19uLCBuY29sPTEpCmBgYAoKYGBge3J9CnJfbCA8LSBub3RpbWluZ19kYXRhICU+JSBmaWx0ZXIoc3ViamVjdCAlaW4lIGxlYXJuZXJzJGlkKSAlPiUKICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgZ2dwbG90KGFlcyh4PXBpZCwgeT1ybXNlX25vdGltaW5nLCBmaWxsPWNvbmRpdGlvbikpICsKICBnZW9tX2JveHBsb3Qod2lkdGg9MC43KSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsIDgsIGJ5PTEpKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDIiKSkgKwogIGxhYnModGl0bGU9IlJNU0UgU2NvcmVzIC0gTGVhcm5lcnMiLCAKICAgICAgICAgICAgc3VidGl0bGU9Ikdyb3VwZWQgYnkgcGhyYXNlIiwKICAgICAgICAgICAgeD0iUGhyYXNlIGlkIiwgeT0iUk1TRSIpIAoKcl9uIDwtIG5vdGltaW5nX2RhdGEgJT4lIGZpbHRlcihzdWJqZWN0ICVpbiUgbmF0aXZlcyRpZCkgJT4lCiAgbXV0YXRlKHBpZCA9IGZjdF9yZWxldmVsKHBpZCwgIjIiLCAiMmJpcyIsICI3IiwgIjdiaXMiLCAiOCIsICI4YmlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIiwgIjEwYmlzIiwgIjExIiwgIjExYmlzIiwgIjIxIiwgIjIxYmlzIikpICU+JQogIGdncGxvdChhZXMoeD1waWQsIHk9cm1zZV9ub3RpbWluZywgZmlsbD1jb25kaXRpb24pKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoPTAuNykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCA4LCBieT0xKSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiUm95YWwyIikpICsKICBsYWJzKHRpdGxlPSJSTVNFIFNjb3JlcyAtIE5hdGl2ZXMiLCAKICAgICAgICAgICAgc3VidGl0bGU9Ikdyb3VwZWQgYnkgcGhyYXNlIiwKICAgICAgICAgICAgeD0iUGhyYXNlIGlkIiwgeT0iUk1TRSIpIAoKZ3JpZC5hcnJhbmdlKHJfbCwgcl9uLCBuY29sPTEpCmBgYAoKIyMgQnkgUGhyYXNlIGFuZCBNdXNpY2lhbi9Ob24tbXVzaWNpYW4KCkluIHRlcm1zIG9mIGNvcnJlbGF0aW9uLCBtdXNpY2lhbnMgZGlkIG11Y2ggYmV0dGVyIHRoYW4gbm9uLW11c2ljaWFucyBpbiBibGluZCBjaGlyb25vbXkgZm9yIGEgZmV3IHNwZWNpZmljIHBocmFzZXMgKGUuZy4gMiwgNywgOCkuIFNvbWUgcGhyYXNlcyB3ZXJlIGRpZmZpY3VsdCBmb3IgZXZlcnlvbmUgKDEwYmlzLCAyMSksIGJ1dCBtdXNpY2lhbnMgc3RpbGwgZGlkIGJldHRlci4KCmBgYHtyfQpjX20gPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBtdXNpY2lhbnMkaWQpICU+JQogIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PWNvcnJfbm90aW1pbmcsIGZpbGw9Y29uZGl0aW9uKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aD0wLjcpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoLTAuOCwgMSwgYnk9MC4yKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogIGxhYnModGl0bGU9IkNvcnJlbGF0aW9uIFNjb3Jlcywgbm8gdGltaW5nIC0gTXVzaWNpYW5zIiwgCiAgICAgICAgICAgIHN1YnRpdGxlPSJHcm91cGVkIGJ5IHBocmFzZSIsCiAgICAgICAgICAgIHg9IlBocmFzZSBpZCIsIHk9IkNvcnJlbGF0aW9uIikgIysgdGhlbWUoYXNwZWN0LnJhdGlvPTAuNCkKCmNfbm0gPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBub25tdXMgJGlkKSAlPiUKICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgZ2dwbG90KGFlcyh4PXBpZCwgeT1jb3JyX25vdGltaW5nLCBmaWxsPWNvbmRpdGlvbikpICsKICBnZW9tX2JveHBsb3Qod2lkdGg9MC43KSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PTAuMikpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiTW9vbnJpc2UzIikpICsKICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiBTY29yZXMsIG5vIHRpbWluZyAtIE5vbi1tdXNpY2lhbnMiLCAKICAgICAgICAgICAgc3VidGl0bGU9Ikdyb3VwZWQgYnkgcGhyYXNlIiwKICAgICAgICAgICAgeD0iUGhyYXNlIGlkIiwgeT0iQ29ycmVsYXRpb24iKSAjKyB0aGVtZShhc3BlY3QucmF0aW89MC40KQoKZ3JpZC5hcnJhbmdlKGNfbSwgY19ubSwgbmNvbD0xKQpgYGAKCgpgYGB7cn0Kcl9tIDwtIG5vdGltaW5nX2RhdGEgJT4lIGZpbHRlcihzdWJqZWN0ICVpbiUgbXVzaWNpYW5zJGlkKSAlPiUKICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgZ2dwbG90KGFlcyh4PXBpZCwgeT1ybXNlX25vdGltaW5nLCBmaWxsPWNvbmRpdGlvbikpICsKICBnZW9tX2JveHBsb3Qod2lkdGg9MC43KSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsIDgsIGJ5PTEpKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHdlc19wYWxldHRlKCJSb3lhbDIiKSkgKwogIGxhYnModGl0bGU9IlJNU0UgU2NvcmVzIC0gTXVzaWNpYW5zIiwgCiAgICAgICAgICAgIHN1YnRpdGxlPSJHcm91cGVkIGJ5IHBocmFzZSIsCiAgICAgICAgICAgIHg9IlBocmFzZSBpZCIsIHk9IlJNU0UiKSAKCnJfbm0gPC0gbm90aW1pbmdfZGF0YSAlPiUgZmlsdGVyKHN1YmplY3QgJWluJSBub25tdXMkaWQpICU+JQogIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PXJtc2Vfbm90aW1pbmcsIGZpbGw9Y29uZGl0aW9uKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aD0wLjcpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwgOCwgYnk9MSkpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIlJveWFsMiIpKSArCiAgbGFicyh0aXRsZT0iUk1TRSBTY29yZXMgLSBOb25tdXMiLCAKICAgICAgICAgICAgc3VidGl0bGU9Ikdyb3VwZWQgYnkgcGhyYXNlIiwKICAgICAgICAgICAgeD0iUGhyYXNlIGlkIiwgeT0iUk1TRSIpIAoKZ3JpZC5hcnJhbmdlKHJfbSwgcl9ubSwgbmNvbD0xKQpgYGAKCgojIFRha2luZyBUaW1pbmcgaW50byBhY2NvdW50CgpGb3IgZ2VzdHVyYWwgY29tcGFyaXNvbnMsIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgd2UgYXJlIGNvbXBhcmluZyB3aXRoIHRoZSByaWdodCBwYXJ0IG9mIHRoZSBvcmlnaW5hbCBzaWduYWwuIFRoZSBwYXJ0IG9mIHRoZSByZWZlcmVuY2Ugc2lnbmFsIHRvIGJlIGNvbXBhcmVkIGlzIHRha2VuIGZyb20gdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIHNjcnViIHZhbHVlcyBvZiB0aGUgZ2VzdHVyZS4gVGhlIHRpbWluZyBvZiB0aGUgZ2VzdHVyZSBpcyBzY2FsZWQgbGluZWFybHkgdG8gbWF0Y2ggdGhlIHRpbWluZyBvZiB0aGUgcmVmZXJlbmNlLgoKRm9yIHZvY2FsIGNvbXBhcmlzb25zLCB0aGUgcGFydCBvZiB0aGUgcmVjb3JkaW5nIGNvbnRhaW5pbmcgdGhlIHV0dGVyYW5jZSBpcyBsYWJlbGVkIGZvciBib3RoIHRoZSByZWZlcmVuY2UgYW5kIHN1YmplY3QgcmVjb3JkaW5ncy4gVGhlIHRpbWluZyBvZiB0aGUgdm9jYWwgcmVjb3JkaW5nIGlzIHNjYWxlZCBsaW5lYXJseSB0byBtYXRjaCB0aGUgcmVmZXJlbmNlLiBObyB0aW1lIHdhcnBpbmcgd2FzIGRvbmUgaW4gb3JkZXIgdG8gcHJlc2VydmUgdGhlIG9yaWdpbmFsIHJoeXRobSBvZiB0aGUgcmVjb3JkaW5nLiAgCgoKYGBge3J9CiMgRm9yIGdlc3R1cmUgZGF0YSwgb25seSBrZWVwIHRoZSBwcm9zb2dyYW0gY29tcGFyaXNvbnMgYnV0IGNhbGwgdGhlbSB0aGUgc2FtZSB0aGluZyBhcyB0aGUgY29ycmVzcG9uZGluZyBjb21wYXJpc29ucyBmb3Igdm9pY2UKZ2VzdF9kYXRhMiA8LSBhbGxfZGF0YSAlPiUgZmlsdGVyKHR5cGU9PSdnZXN0dXJlJykgJT4lIG11dGF0ZShjb3JyX25vdGltaW5nID0gY29ycl9wc2dfbm90aW1pbmcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJtc2Vfbm90aW1pbmcgPSBybXNlX3BzZ19ub3RpbWluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyID0gY29ycl9wc2csIHJtc2U9IHJtc2VfcHNnKSAKbG9uZ19kYXRhIDwtIGFsbF9kYXRhICU+JSBmaWx0ZXIodHlwZT09ICd2b2ljZScpICU+JSBiaW5kX3Jvd3MoZ2VzdF9kYXRhMikgJT4lIAogICAgICAgICAgICAgIyBHZXQgcmlkIG9mIGNvbHVtbnMgY29udGFpbmluZyB0aGUgcHJvc29ncmFtIGNvbXBhcmlzb25zCiAgICAgICAgICAgICBtdXRhdGUoY29ycl9wc2cgPSBOVUxMLCBybXNlX3BzZyA9IE5VTEwsIGNvcnJfcHNnX25vdGltaW5nID0gTlVMTCwgcm1zZV9wc2dfbm90aW1pbmcgPSBOVUxMKSAlPiUKICAgICAgICAgICAgICMgTWFrZSBsb25nIHZlcnNpb24gb2YgZGF0YQogICAgICAgICAgICAgcGl2b3RfbG9uZ2VyKGMoJ2NvcnInLCAnY29ycl9ub3RpbWluZycsICdybXNlJywgJ3Jtc2Vfbm90aW1pbmcnKSwgbmFtZXNfdG8gPSAibWV0cmljcyIsIHZhbHVlc190byA9ICJzY29yZSIpCmBgYAoKIyMgT3ZlcmFsbAoKSW50ZXJlc3RpbmcsIHRoZSBibGluZCBjaGlyb25vbXkgbWVkaWFuIHNjb3JlcyBkb24ndCBjaGFuZ2UgbXVjaCBiZWNhdXNlIHRoZXkgYXJlIGFscmVhZHkgbm90IHNvIGdyZWF0LiBUaGUgc2NvcmVzIGZvciB0aGUgb3RoZXIgY29uZGl0aW9ucyBhcmUgd29yc2UuIEludGVyZXN0aW5nbHksIGd1aWRlZCBjaGlyb25vbXkgcGVyZm9ybXMgdGhlIGJlc3Qgd2hlbiB0aW1pbmcgaXMgdGFrZW4gaW50byBhY2NvdW50LiBFdmVuIHRob3VnaCBpdHMgc2NvcmVzIGFyZSBzbGlnaHRseSB3b3JzZSB0aGFuIHdoZW4gdGltaW5nIGlzIG5vdCB0YWtlbiBpbnRvIGFjY291bnQsIGl0IHN0aWxsIG1hbmFnZXMgdG8gaGF2ZSAiZ29vZCIgc2NvcmVzIChpbiBjb21wYXJpc29uIHdpdGggcmVzdWx0cyBmcm9tIGQnQWxlc3NhbmRybyAyMDExKSAtLSBhIG1lZGlhbiBjb3JyZWxhdGlvbiBvZiA+MC44IGFuZCBtZWRpYW4gUk1TRSBhcm91bmQgMlNULiAKCkZvciByZWFkaW5nLCBpdCBpcyBub3JtYWwgdGhhdCB0aGVyZSB3b3VsZCBiZSBtb3JlIHZhcmlhdGlvbiBpbiB0aW1pbmcuIAoKYGBge3J9CmxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAnY29ycl9ub3RpbWluZycgfCBtZXRyaWNzID09ICdjb3JyJykgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbiwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PTAuMikpICsKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24sIHRpbWluZyB2cyBuby10aW1pbmciKQoKYGBgCgpgYGB7cn0KbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdybXNlX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ3Jtc2UnKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwgOCwgYnk9MSkpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaXRoIHRpbWluZyIsICJObyB0aW1pbmciKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTIiKSkgKwogICAgICAgICAgICAgIGxhYnModGl0bGU9IlJNU0UsIHRpbWluZyB2cyBuby10aW1pbmciKQpgYGAKCiMjIExlYXJuZXJzIHZzIE5hdGl2ZXMKCk5vdCBzbyBtdWNoIGRpZmZlcmVuY2UgYmV0d2VlbiBuYXRpdmVzIGFuZCBub24tbmF0aXZlcyB3aGVuIHRpbWluZyBpcyB0YWtlbiBpbnRvIGFjY291bnQuCgpgYGB7cn0KbCA8LSBsb25nX2RhdGEgJT4lIGZpbHRlcihtZXRyaWNzPT0gJ2NvcnJfbm90aW1pbmcnIHwgbWV0cmljcyA9PSAnY29ycicpICU+JQogICAgICAgICAgICAgIGZpbHRlcihzdWJqZWN0ICVpbiUgbGVhcm5lcnMkaWQpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1jb25kaXRpb24sIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0uMikpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIGxhYnModGl0bGU9IkNvcnJlbGF0aW9uLCB0aW1pbmcgdnMgbm8tdGltaW5nIiwgc3VidGl0bGU9IkxlYXJuZXJzIikKCm4gPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdjb3JyX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ2NvcnInKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoc3ViamVjdCAlaW4lIG5hdGl2ZXMkaWQpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1jb25kaXRpb24sIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0uMikpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIGxhYnMoc3VidGl0bGU9Ik5hdGl2ZXMiKQoKZ3JpZC5hcnJhbmdlKGwsIG4sIG5jb2w9MSkKCmBgYApgYGB7cn0KbCA8LSBsb25nX2RhdGEgJT4lIGZpbHRlcihtZXRyaWNzPT0gJ3Jtc2Vfbm90aW1pbmcnIHwgbWV0cmljcyA9PSAncm1zZScpICU+JQogICAgICAgICAgICAgIGZpbHRlcihzdWJqZWN0ICVpbiUgbGVhcm5lcnMkaWQpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1jb25kaXRpb24sIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwgOCwgYnk9MSkpICsgCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMiIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iUk1TRSwgdGltaW5nIHZzIG5vLXRpbWluZyIsIHN1YnRpdGxlPSJMZWFybmVycyIpCgpuIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAncm1zZV9ub3RpbWluZycgfCBtZXRyaWNzID09ICdybXNlJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBuYXRpdmVzJGlkKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwgOCwgYnk9MSkpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTIiKSkgKwogICAgICAgICAgICAgIGxhYnMoc3VidGl0bGU9Ik5hdGl2ZXMiKQoKZ3JpZC5hcnJhbmdlKGwsIG4sIG5jb2w9MSkKCmBgYAoKIyMgTXVzaWNpYW5zIHZzIE5vbi1tdXNpY2lhbnMKCk5vdCBiaWcgZGlmZmVyZW5jZSBiZXR3ZWVuIG11c2ljaWFucyBhbmQgbm9uLW11c2ljaWFucyBlaXRoZXIgd2hlbiB0aW1pbmcgaXMgdGFrZW4gaW50byBhY2NvdW50LgoKYGBge3J9Cm0gPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdjb3JyX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ2NvcnInKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoc3ViamVjdCAlaW4lIG11c2ljaWFucyRpZCkgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbiwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PS4yKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24sIHRpbWluZyB2cyBuby10aW1pbmciLCBzdWJ0aXRsZT0iTXVzaWNpYW5zIikKCm5tIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAnY29ycl9ub3RpbWluZycgfCBtZXRyaWNzID09ICdjb3JyJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBub25tdXMkaWQpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1jb25kaXRpb24sIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoLTAuOCwgMSwgYnk9LjIpKSArIAogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIGxhYnMoc3VidGl0bGU9Ik5vbi1tdXNpY2lhbnMiKQoKZ3JpZC5hcnJhbmdlKG0sIG5tLCBuY29sPTEpCmBgYAoKYGBge3J9Cm0gPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdybXNlX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ3Jtc2UnKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoc3ViamVjdCAlaW4lIG11c2ljaWFucyRpZCkgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbiwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsIDgsIGJ5PTEpKSArIAogICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQ29tcGFyaXNvbiB0eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaXRoIHRpbWluZyIsICJObyB0aW1pbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz13ZXNfcGFsZXR0ZSgiTW9vbnJpc2UyIikpICsKICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJSTVNFLCB0aW1pbmcgdnMgbm8tdGltaW5nIiwgc3VidGl0bGU9IkxlYXJuZXJzIikKCm5tIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAncm1zZV9ub3RpbWluZycgfCBtZXRyaWNzID09ICdybXNlJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBub25tdXMkaWQpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1jb25kaXRpb24sIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCA4LCBieT0xKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMiIpKSArCiAgICAgICAgICAgICAgbGFicyhzdWJ0aXRsZT0iTmF0aXZlcyIpCgpncmlkLmFycmFuZ2UobSwgbm0sIG5jb2w9MSkKCmBgYAoKIyBCeSBQaHJhc2UKCkJ5IGNvbXBhcmlpbmcgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBndWlkZWQgY2hpcm9ub215IHdpdGggYW5kIHdpdGhvdXQgdGltaW5nIHRha2VuIGludG8gYWNjb3VudCwgd2UgY2FuIHNlZSB0aGF0IHNvbWUgcGhyYXNlcyB3ZXJlIHRyaWNraWVyIHRvIGNvbnRyb2wgdGhlIHRpbWluZyBvZiB0aGFuIG90aGVycyAoZS5nLiA3YmlzLCAxMCwgMjEsIDIxYmlzKQoKSSdtIG5vdCBzdXJlIGhvdyBtZWFuaW5nZnVsIGl0IGlzIHRvIGNvbXBhcmUgdGhlIHZvY2FsIHByb251bmNpYXRpb25zIHdpdGggd2l0aG91dCBkeW5hbWljIHRpbWUgd2FycGluZyBiZWNhdXNlIHRoZXJlIGlzIG5hdHVyYWwgdmFyaWF0aW9uIGluIHRoZSB2b2ljZS4gCgpgYGB7cn0KY2kgPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdjb3JyX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ2NvcnInKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoY29uZGl0aW9uPT0nZ3VpZGUnKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PXBpZCwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PS4yKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24sIHRpbWluZyB2cyBuby10aW1pbmciLCBzdWJ0aXRsZT0iR3VpZGVkIENoaXJvbm9teSIpCgp2aSA8LSBsb25nX2RhdGEgJT4lIGZpbHRlcihtZXRyaWNzPT0gJ2NvcnJfbm90aW1pbmcnIHwgbWV0cmljcyA9PSAnY29ycicpICU+JQogICAgICAgICAgICAgIGZpbHRlcihjb25kaXRpb249PSdpbWl0YXRpb24nKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PXBpZCwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PS4yKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24sIHRpbWluZyB2cyBuby10aW1pbmciLCBzdWJ0aXRsZT0iVm9jYWwgQ29tcGFyaXNvbiIpCgpncmlkLmFycmFuZ2UoY2ksIHZpLCBuY29sPTEpCmBgYAoKYGBge3J9CmNpIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAncm1zZV9ub3RpbWluZycgfCBtZXRyaWNzID09ICdybXNlJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKGNvbmRpdGlvbj09J2d1aWRlJykgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHBpZCA9IGZjdF9yZWxldmVsKHBpZCwgIjIiLCAiMmJpcyIsICI3IiwgIjdiaXMiLCAiOCIsICI4YmlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIiwgIjEwYmlzIiwgIjExIiwgIjExYmlzIiwgIjIxIiwgIjIxYmlzIikpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1waWQsIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCA4LCBieT0xKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIlJveWFsMiIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iUk1TRSwgdGltaW5nIHZzIG5vLXRpbWluZyIsIHN1YnRpdGxlPSJHdWlkZWQgQ2hpcm9ub215IikKCnZpIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAncm1zZV9ub3RpbWluZycgfCBtZXRyaWNzID09ICdybXNlJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKGNvbmRpdGlvbj09J2ltaXRhdGlvbicpICU+JQogICAgICAgICAgICAgIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwgOCwgYnk9MSkpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJSb3lhbDIiKSkgKwogICAgICAgICAgICAgIGxhYnModGl0bGU9IlJNU0UsIHRpbWluZyB2cyBuby10aW1pbmciLCBzdWJ0aXRsZT0iVm9jYWwgQ29tcGFyaXNvbiIpCgpncmlkLmFycmFuZ2UoY2ksIHZpLCBuY29sPTEpCmBgYAoKIyBCeSBQaHJhc2UgYW5kIHN1YmplY3QgZ3JvdXBzCgojIyBGb3IgZ3VpZGVkIGNoaXJvbm9teQpTZWVtcyB0byBiZSBhbiBlcXVhbGl6ZXIgYmV0d2VlbiBuYXRpdmVzIGFuZCBub24tbmF0aXZlcy4gTm90IGh1Z2UgYW1vdW50IG9mIGRpZmZlcmVuY2UuCgpgYGB7cn0KbGcgPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdjb3JyX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ2NvcnInKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoc3ViamVjdCAlaW4lIGxlYXJuZXJzJGlkKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoY29uZGl0aW9uPT0nZ3VpZGUnKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PXBpZCwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PS4yKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24sIHRpbWluZyB2cyBuby10aW1pbmciLCBzdWJ0aXRsZT0iR3VpZGVkIENoaXJvbm9teSwgTGVhcm5lcnMiKQoKbmcgPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdjb3JyX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ2NvcnInKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoc3ViamVjdCAlaW4lIG5hdGl2ZXMkaWQpICU+JQogICAgICAgICAgICAgIGZpbHRlcihjb25kaXRpb249PSdndWlkZScpICU+JQogICAgICAgICAgICAgIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoLTAuOCwgMSwgYnk9LjIpKSArIAogICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQ29tcGFyaXNvbiB0eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaXRoIHRpbWluZyIsICJObyB0aW1pbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz13ZXNfcGFsZXR0ZSgiTW9vbnJpc2UzIikpICsKICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiwgdGltaW5nIHZzIG5vLXRpbWluZyIsIHN1YnRpdGxlPSJHdWlkZWQgQ2hpcm9ub215LCBOYXRpdmVzIikKCmdyaWQuYXJyYW5nZShsZywgbmcsIG5jb2w9MSkKYGBgCgojIyMgRm9yIGJsaW5kIGNoaXJvbm9teToKCkEgY291cGxlIG9mIHBocmFzZXMgbmF0aXZlcyBoYWQgbW9yZSB0cm91YmxlIHdpdGguIENvdWxkIGJlIHRoYXQgdGhleSBhcmUgbGVzcyBjb25zY2lvdXMgb2YgdGhlIGZyZXF1ZW5jeSBjdXJ2ZT8KCmBgYHtyfQpsYiA8LSBsb25nX2RhdGEgJT4lIGZpbHRlcihtZXRyaWNzPT0gJ2NvcnJfbm90aW1pbmcnIHwgbWV0cmljcyA9PSAnY29ycicpICU+JQogICAgICAgICAgICAgIGZpbHRlcihzdWJqZWN0ICVpbiUgbGVhcm5lcnMkaWQpICU+JQogICAgICAgICAgICAgIGZpbHRlcihjb25kaXRpb249PSdibGluZCcpICU+JQogICAgICAgICAgICAgIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoLTAuOCwgMSwgYnk9LjIpKSArIAogICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQ29tcGFyaXNvbiB0eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaXRoIHRpbWluZyIsICJObyB0aW1pbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz13ZXNfcGFsZXR0ZSgiTW9vbnJpc2UzIikpICsKICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiwgdGltaW5nIHZzIG5vLXRpbWluZyIsIHN1YnRpdGxlPSJCbGluZCBDaGlyb25vbXksIExlYXJuZXJzIikKCm5iIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAnY29ycl9ub3RpbWluZycgfCBtZXRyaWNzID09ICdjb3JyJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBuYXRpdmVzJGlkKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoY29uZGl0aW9uPT0nYmxpbmQnKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PXBpZCwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PS4yKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24sIHRpbWluZyB2cyBuby10aW1pbmciLCBzdWJ0aXRsZT0iQmxpbmQgQ2hpcm9ub215LCBOYXRpdmVzIikKCmdyaWQuYXJyYW5nZShsYiwgbmIsIG5jb2w9MSkKYGBgCgojIyMgVm9jYWwgSW1pdGF0aW9uCgpOb3QgdG9vIG11Y2ggZGlmZmVyZW5jZS4gTmF0aXZlcyBoYXZlIG1vcmUgdmFyaWF0aW9uLgoKYGBge3J9CmxpIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAnY29ycl9ub3RpbWluZycgfCBtZXRyaWNzID09ICdjb3JyJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBsZWFybmVycyRpZCkgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKGNvbmRpdGlvbj09J2ltaXRhdGlvbicpICU+JQogICAgICAgICAgICAgIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoLTAuOCwgMSwgYnk9LjIpKSArIAogICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQ29tcGFyaXNvbiB0eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaXRoIHRpbWluZyIsICJObyB0aW1pbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz13ZXNfcGFsZXR0ZSgiTW9vbnJpc2UzIikpICsKICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiwgdGltaW5nIHZzIG5vLXRpbWluZyIsIHN1YnRpdGxlPSJJbWl0YXRpb24sIExlYXJuZXJzIikKCm5pIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAnY29ycl9ub3RpbWluZycgfCBtZXRyaWNzID09ICdjb3JyJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBuYXRpdmVzJGlkKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoY29uZGl0aW9uPT0naW1pdGF0aW9uJykgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHBpZCA9IGZjdF9yZWxldmVsKHBpZCwgIjIiLCAiMmJpcyIsICI3IiwgIjdiaXMiLCAiOCIsICI4YmlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIiwgIjEwYmlzIiwgIjExIiwgIjExYmlzIiwgIjIxIiwgIjIxYmlzIikpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1waWQsIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0uMikpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIGxhYnModGl0bGU9IkNvcnJlbGF0aW9uLCB0aW1pbmcgdnMgbm8tdGltaW5nIiwgc3VidGl0bGU9IkltaXRhdGlvbiwgTmF0aXZlcyIpCgpncmlkLmFycmFuZ2UobGksIG5pLCBuY29sPTEpCmBgYAoKIyMjIFZvY2FsIFJlYWRpbmlnCgpOb3QgdG9vIG11Y2ggZGlmZmVyZW5jZS4gTmF0aXZlcyBoYXZlIG1vcmUgdmFyaWF0aW9uLiBOb24tbmF0aXZlcyBzZWVtZWQgdG8gaGF2ZSBpc3N1ZXMgd2l0aCAxMCwgMTBiaXMsIDIxLgoKYGBge3J9CgpsaSA8LSBsb25nX2RhdGEgJT4lIGZpbHRlcihtZXRyaWNzPT0gJ2NvcnJfbm90aW1pbmcnIHwgbWV0cmljcyA9PSAnY29ycicpICU+JQogICAgICAgICAgICAgIGZpbHRlcihzdWJqZWN0ICVpbiUgbGVhcm5lcnMkaWQpICU+JQogICAgICAgICAgICAgIGZpbHRlcihjb25kaXRpb249PSdsZWN0dXJlJykgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHBpZCA9IGZjdF9yZWxldmVsKHBpZCwgIjIiLCAiMmJpcyIsICI3IiwgIjdiaXMiLCAiOCIsICI4YmlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIiwgIjEwYmlzIiwgIjExIiwgIjExYmlzIiwgIjIxIiwgIjIxYmlzIikpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1waWQsIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0uMikpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIGxhYnModGl0bGU9IkNvcnJlbGF0aW9uLCB0aW1pbmcgdnMgbm8tdGltaW5nIiwgc3VidGl0bGU9IkxlY3R1cmUsIExlYXJuZXJzIikKCm5pIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAnY29ycl9ub3RpbWluZycgfCBtZXRyaWNzID09ICdjb3JyJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBuYXRpdmVzJGlkKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoY29uZGl0aW9uPT0nbGVjdHVyZScpICU+JQogICAgICAgICAgICAgIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoLTAuOCwgMSwgYnk9LjIpKSArIAogICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQ29tcGFyaXNvbiB0eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaXRoIHRpbWluZyIsICJObyB0aW1pbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz13ZXNfcGFsZXR0ZSgiTW9vbnJpc2UzIikpICsKICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiwgdGltaW5nIHZzIG5vLXRpbWluZyIsIHN1YnRpdGxlPSJMZWN0dXJlLCBOYXRpdmVzIikKCmdyaWQuYXJyYW5nZShsaSwgbmksIG5jb2w9MSkKYGBgCgojIyMgR3VpZGVkIENoaXJvbm9teSAtIG11c2ljaWFucyB2cyBub24tbXVzaWNpYW5zCgpNdXNpY2lhbnMgZG9uJ3QgZG8gYmV0dGVyIGZvciBndWlkZWQgY2hpcm9ub215CgpgYGB7cn0KbWcgPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdjb3JyX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ2NvcnInKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoc3ViamVjdCAlaW4lIG11c2ljaWFucyRpZCkgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKGNvbmRpdGlvbj09J2d1aWRlJykgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHBpZCA9IGZjdF9yZWxldmVsKHBpZCwgIjIiLCAiMmJpcyIsICI3IiwgIjdiaXMiLCAiOCIsICI4YmlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIiwgIjEwYmlzIiwgIjExIiwgIjExYmlzIiwgIjIxIiwgIjIxYmlzIikpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1waWQsIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0uMikpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIGxhYnModGl0bGU9IkNvcnJlbGF0aW9uLCB0aW1pbmcgdnMgbm8tdGltaW5nIiwgc3VidGl0bGU9Ikd1aWRlZCBDaGlyb25vbXksIE11c2ljaWFucyIpCgpuZyA8LSBsb25nX2RhdGEgJT4lIGZpbHRlcihtZXRyaWNzPT0gJ2NvcnJfbm90aW1pbmcnIHwgbWV0cmljcyA9PSAnY29ycicpICU+JQogICAgICAgICAgICAgIGZpbHRlcihzdWJqZWN0ICVpbiUgbm9ubXVzJGlkKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoY29uZGl0aW9uPT0nZ3VpZGUnKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUocGlkID0gZmN0X3JlbGV2ZWwocGlkLCAiMiIsICIyYmlzIiwgIjciLCAiN2JpcyIsICI4IiwgIjhiaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAiLCAiMTBiaXMiLCAiMTEiLCAiMTFiaXMiLCAiMjEiLCAiMjFiaXMiKSkgJT4lCiAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PXBpZCwgeT1zY29yZSkpICsKICAgICAgICAgICAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGwgPSBtZXRyaWNzKSkgKwogICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKC0wLjgsIDEsIGJ5PS4yKSkgKyAKICAgICAgICAgICAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkNvbXBhcmlzb24gdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiV2l0aCB0aW1pbmciLCAiTm8gdGltaW5nIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9d2VzX3BhbGV0dGUoIk1vb25yaXNlMyIpKSArCiAgICAgICAgICAgICAgbGFicyh0aXRsZT0iQ29ycmVsYXRpb24sIHRpbWluZyB2cyBuby10aW1pbmciLCBzdWJ0aXRsZT0iR3VpZGVkIENoaXJvbm9teSwgTm9uLW11c2ljaWFucyIpCgpncmlkLmFycmFuZ2UobWcsIG5nLCBuY29sPTEpCmBgYAoKIyMjIEJsaW5kIENoaXJvbm9teSAtIG11c2ljaWFucyB2cyBub24tbXVzaWNpYW5zCgpXZSBkb24ndCBsZWFybiBtdWNoIG5ldyBoZXJlLiBNdXNpY2lhbnMgZG8gYmV0dGVyIGZvciBzb21lIHBocmFzZXMgdGhhbiBvdGhlcnMuCgpgYGB7cn0KbWIgPC0gbG9uZ19kYXRhICU+JSBmaWx0ZXIobWV0cmljcz09ICdjb3JyX25vdGltaW5nJyB8IG1ldHJpY3MgPT0gJ2NvcnInKSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoc3ViamVjdCAlaW4lIG11c2ljaWFucyRpZCkgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKGNvbmRpdGlvbj09J2JsaW5kJykgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHBpZCA9IGZjdF9yZWxldmVsKHBpZCwgIjIiLCAiMmJpcyIsICI3IiwgIjdiaXMiLCAiOCIsICI4YmlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwIiwgIjEwYmlzIiwgIjExIiwgIjExYmlzIiwgIjIxIiwgIjIxYmlzIikpICU+JQogICAgICAgICAgICAgIGdncGxvdChhZXMoeD1waWQsIHk9c2NvcmUpKSArCiAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gbWV0cmljcykpICsKICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtMC44LCAxLCBieT0uMikpICsgCiAgICAgICAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJDb21wYXJpc29uIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpdGggdGltaW5nIiwgIk5vIHRpbWluZyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzPXdlc19wYWxldHRlKCJNb29ucmlzZTMiKSkgKwogICAgICAgICAgICAgIGxhYnModGl0bGU9IkNvcnJlbGF0aW9uLCB0aW1pbmcgdnMgbm8tdGltaW5nIiwgc3VidGl0bGU9IkJsaW5kIENoaXJvbm9teSwgTXVzaWNpYW5zIikKCm5iIDwtIGxvbmdfZGF0YSAlPiUgZmlsdGVyKG1ldHJpY3M9PSAnY29ycl9ub3RpbWluZycgfCBtZXRyaWNzID09ICdjb3JyJykgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKHN1YmplY3QgJWluJSBub25tdXMkaWQpICU+JQogICAgICAgICAgICAgIGZpbHRlcihjb25kaXRpb249PSdibGluZCcpICU+JQogICAgICAgICAgICAgIG11dGF0ZShwaWQgPSBmY3RfcmVsZXZlbChwaWQsICIyIiwgIjJiaXMiLCAiNyIsICI3YmlzIiwgIjgiLCAiOGJpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMCIsICIxMGJpcyIsICIxMSIsICIxMWJpcyIsICIyMSIsICIyMWJpcyIpKSAlPiUKICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9cGlkLCB5PXNjb3JlKSkgKwogICAgICAgICAgICAgIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IG1ldHJpY3MpKSArCiAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoLTAuOCwgMSwgYnk9LjIpKSArIAogICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQ29tcGFyaXNvbiB0eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaXRoIHRpbWluZyIsICJObyB0aW1pbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz13ZXNfcGFsZXR0ZSgiTW9vbnJpc2UzIikpICsKICAgICAgICAgICAgICBsYWJzKHRpdGxlPSJDb3JyZWxhdGlvbiwgdGltaW5nIHZzIG5vLXRpbWluZyIsIHN1YnRpdGxlPSJCbGluZCBDaGlyb25vbXksIE5vbi1tdXNpY2lhbnMiKQoKZ3JpZC5hcnJhbmdlKG1iLCBuYiwgbmNvbD0xKQpgYGAK